This notebook outlines my process of generating basic statistical models and exploratory data analysis. This notebook is dependent on the data table gameInfo generated from DataExtraction.RMD.
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
-- Attaching packages --------------------------------------------------------------------------------- tidyverse 1.3.1 --
v tibble 3.1.2 v dplyr 1.0.7
v tidyr 1.1.3 v stringr 1.4.0
v readr 1.4.0 v forcats 0.5.1
v purrr 0.3.4
-- Conflicts ------------------------------------------------------------------------------------ tidyverse_conflicts() --
x dplyr::between() masks data.table::between()
x dplyr::filter() masks plotly::filter(), stats::filter()
x dplyr::first() masks data.table::first()
x dplyr::lag() masks stats::lag()
x dplyr::last() masks data.table::last()
x purrr::transpose() masks data.table::transpose()
library(sjPlot)
Warning: package ‘sjPlot’ was built under R version 4.1.2
Install package "strengejacke" from GitHub (`devtools::install_github("strengejacke/strengejacke")`) to load all sj-packages at once!
library(plotly)
results <- list(
models = list(),
plots = list()
)
data.temp <- list()
Let’s examine the effect of vision score on predicted probability of winning. If the theory is true that controlling vision is integral for winning (which by all intuition it should be) then higher vision score should increase the log odds of victory. ## Just Vision Score
summary(results$models$visionScore)
Call:
glm(formula = win ~ visionScore, family = "binomial", data = gameInfo)
Deviance Residuals:
Min 1Q Median 3Q Max
-1.9622 -1.1513 -0.2429 1.1914 1.2745
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.2254102 0.0040359 -55.85 <2e-16 ***
visionScore 0.0096274 0.0001385 69.50 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 945480 on 682019 degrees of freedom
Residual deviance: 940520 on 682018 degrees of freedom
AIC: 940524
Number of Fisher Scoring iterations: 4
results$plots$visionScore <- plot_model(results$models$visionScore, type = "pred", grid = F)
Data were 'prettified'. Consider using `terms="visionScore [all]"` to get smooth plots.
results$plots$visionScore
$visionScore
So as expected, increasing vision score does appear to increase your chances of victor. So for every point of vision score, the log odds of winning increases by 0.0096 and at a vision score of ~23.4, your win chance is 50%. But what if we wanted to include role (adc, support, etc.)? Is it more important for a particular role to have a high vision score? It should be noted that the average and standard deviation of vision score is 23.49 and 19.96 respectively, so the large vision scores above 100 are very rare and the win rate should not be taken as accurate.
results$models$visionScore.role <- glm(win ~ visionScore*individualPosition, family = "binomial", data = gameInfo %>% filter(individualPosition != "Invalid"))
summary(results$models$visionScore.role)
Call:
glm(formula = win ~ visionScore * individualPosition, family = "binomial",
data = gameInfo %>% filter(individualPosition != "Invalid"))
Deviance Residuals:
Min 1Q Median 3Q Max
-2.4343 -1.1539 0.7172 1.1776 1.3968
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.4334489 0.0117634 -36.847 < 2e-16 ***
visionScore 0.0095649 0.0002294 41.692 < 2e-16 ***
individualPositionBOTTOM 0.0158948 0.0161149 0.986 0.324
individualPositionMIDDLE -0.0057545 0.0165318 -0.348 0.728
individualPositionJUNGLE -0.0688483 0.0165850 -4.151 3.31e-05 ***
individualPositionTOP 0.0883103 0.0162263 5.442 5.26e-08 ***
visionScore:individualPositionBOTTOM 0.0149763 0.0005965 25.106 < 2e-16 ***
visionScore:individualPositionMIDDLE 0.0160015 0.0006355 25.178 < 2e-16 ***
visionScore:individualPositionJUNGLE 0.0140470 0.0005503 25.525 < 2e-16 ***
visionScore:individualPositionTOP 0.0122536 0.0006491 18.879 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 943982 on 680939 degrees of freedom
Residual deviance: 934534 on 680930 degrees of freedom
AIC: 934554
Number of Fisher Scoring iterations: 4
As it turns out, having laners / junglers that ward is a very strong indicator of success. If your laners / jungler have a vision score of less than 25, they are actively trolling. Adding time is too big to handle on my local machine - instead I will divide the data into segments and run the individual logistic regressions. I assume since the effect of vision score is near uniform across the non support roles that a model of just the support role and just one other role should be sufficient. ## Include Game Time
summary(results$models$visionScore.time.support)
Call:
glm(formula = win ~ visionScore * timePlayed, family = "binomial",
data = gameInfo %>% filter(individualPosition == "UTILITY"))
Deviance Residuals:
Min 1Q Median 3Q Max
-1.9891 -1.1543 0.7182 1.1475 1.8167
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.931e-01 3.436e-02 -5.619 1.92e-08 ***
visionScore 3.455e-02 8.837e-04 39.096 < 2e-16 ***
timePlayed -2.301e-02 1.332e-03 -17.276 < 2e-16 ***
visionScore:timePlayed -5.150e-04 2.558e-05 -20.135 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 188422 on 135917 degrees of freedom
Residual deviance: 184589 on 135914 degrees of freedom
AIC: 184597
Number of Fisher Scoring iterations: 4
data.temp$visionScore <- expand_grid(
visionScore = seq(min(gameInfo$visionScore), mean(gameInfo$visionScore) + 4*sd(gameInfo$visionScore), length.out = 50),
timePlayed = seq(5, 60, length.out = 50)
)
GET_SURFACE <- function(MODEL, TABLE = data.temp$visionScore){
table.temp <- TABLE %>%
mutate(
p_win = 1-exp(MODEL$coefficients[[1]] + MODEL$coefficients[[2]]*visionScore + MODEL$coefficients[[3]]*timePlayed + MODEL$coefficients[[4]]*visionScore*timePlayed)/(1 + exp(MODEL$coefficients[[1]] + MODEL$coefficients[[2]]*visionScore + MODEL$coefficients[[3]]*timePlayed + MODEL$coefficients[[4]]*visionScore*timePlayed)
)
)
output.raw <- list()
for(i in 0:49){
output.raw[[i+1]] <- table.temp$p_win[(50*i+1):((i+1)*50)]
}
output <- rbind(output.raw[1:50]) %>%
return()
}
data.temp$visionScore.support <- GET_SURFACE(results$models$visionScore.time.support)
data.temp$visionScore.nonSupport <- GET_SURFACE(results$models$visionScore.time.nonSupport)
results$plots$visionScore.time.support <- plot_ly(
x = seq(min(gameInfo$visionScore), mean(gameInfo$visionScore) + 4*sd(gameInfo$visionScore), length.out = 50),
y = seq(5, 60, length.out = 50),
z = data.temp$visionScore.support,
type = "surface"
) %>%
layout(
scene = list(
xaxis = list(title = "Vision Score"),
yaxis = list(title = "Game Time (Mins)"),
zaxis = list(title = "Probability of winning")
)
)
results$plots$visionScore.time.support
results$plots$visionScore.time.nonSupport <- plot_ly(
x = seq(min(gameInfo$visionScore), mean(gameInfo$visionScore) + 4*sd(gameInfo$visionScore), length.out = 50),
y = seq(5, 60, length.out = 50),
z = data.temp$visionScore.nonSupport,
type = "surface"
) %>%
layout(
scene = list(
xaxis = list(title = "Vision Score"),
yaxis = list(title = "Game Time (Mins)"),
zaxis = list(title = "Probability of winning")
)
)
results$plots$visionScore.time.nonSupport
data.temp$contour.visionScore.support <- tibble(gameTime = 1:12*5) %>%
mutate(visionScore = (-results$models$visionScore.time.support$coefficients[[1]]-results$models$visionScore.time.support$coefficients[[3]]*gameTime)/(results$models$visionScore.time.support$coefficients[[2]] + results$models$visionScore.time.support$coefficients[[4]]*gameTime))
data.temp$contour.visionScore.nonSupport <- tibble(gameTime = 1:12*5) %>%
mutate(visionScore = (-results$models$visionScore.time.nonSupport$coefficients[[1]]-results$models$visionScore.time.nonSupport$coefficients[[3]]*gameTime)/(results$models$visionScore.time.nonSupport$coefficients[[2]] + results$models$visionScore.time.nonSupport$coefficients[[4]]*gameTime))
data.temp$contour.visionScore.support
data.temp$contour.visionScore.nonSupport
So for a support, you want your vision score to be around 25 at 20 minutes, 45 at 30 minutes, and 80 at 40 minutes to have a 50% chance of winning. For a non-support, you want your vision score to be around 10 at 20 minutes, 20 at 30 minutes, and 30 at 40 minutes.
It’s a common idea that the ADC role has been considered useless for this season - let’s see what the data has to say about that!
data.temp$goldPercent <- gameInfo %>%
group_by(match, win) %>% # here win is just used to group team
mutate(team_gold = sum(goldEarned), goldEarned = goldEarned / team_gold) %>%
ungroup()
results$models$goldPercent <- glm(win ~ goldEarned*individualPosition, data = data.temp$goldPercent %>% filter(individualPosition != "Invalid"), family = "binomial")
summary(results$models$goldPercent)
Call:
glm(formula = win ~ goldEarned * individualPosition, family = "binomial",
data = data.temp$goldPercent %>% filter(individualPosition !=
"Invalid"))
Deviance Residuals:
Min 1Q Median 3Q Max
-1.323 -1.180 1.097 1.175 1.460
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 0.59312 0.03422 17.34 <2e-16 ***
goldEarned -3.73638 0.21356 -17.50 <2e-16 ***
individualPositionBOTTOM -0.95585 0.04898 -19.52 <2e-16 ***
individualPositionMIDDLE -0.52590 0.04799 -10.96 <2e-16 ***
individualPositionJUNGLE -0.59060 0.04850 -12.18 <2e-16 ***
individualPositionTOP -0.59217 0.04729 -12.52 <2e-16 ***
goldEarned:individualPositionBOTTOM 5.47693 0.26768 20.46 <2e-16 ***
goldEarned:individualPositionMIDDLE 3.43901 0.26587 12.94 <2e-16 ***
goldEarned:individualPositionJUNGLE 3.67854 0.26801 13.72 <2e-16 ***
goldEarned:individualPositionTOP 3.76405 0.26362 14.28 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 943982 on 680939 degrees of freedom
Residual deviance: 943546 on 680930 degrees of freedom
AIC: 943566
Number of Fisher Scoring iterations: 3
So it would appear that having your carry fed is actually a very strong indicator of win percentage. So why might people believe that ADC is useless? Let’s add tier as a covariate and see what we see. (Also as a note, winrate drops off a cliff if support steals all the gold so good to know…as a support main) ## Add tier
summary(results$models$goldPercent.tier)
Call:
glm(formula = win ~ goldEarned * individualPosition * tier, family = "binomial",
data = goldPercent %>% filter(individualPosition != "Invalid"))
Deviance Residuals:
Min 1Q Median 3Q Max
-1.346 -1.179 1.081 1.176 1.492
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 0.7540872 0.0900390 8.375 < 2e-16 ***
goldEarned -4.4437284 0.5216559 -8.519 < 2e-16 ***
individualPositionBOTTOM -0.9870719 0.1257502 -7.849 4.18e-15 ***
individualPositionMIDDLE -0.8395340 0.1217085 -6.898 5.28e-12 ***
individualPositionJUNGLE -0.7553173 0.1208626 -6.249 4.12e-10 ***
individualPositionTOP -0.6528942 0.1213688 -5.379 7.47e-08 ***
tierBRONZE 0.0008867 0.1291223 0.007 0.994521
tierSILVER -0.0263694 0.1248695 -0.211 0.832750
tierGOLD -0.1054959 0.1243836 -0.848 0.396355
tierPLATINUM -0.3440531 0.1275268 -2.698 0.006978 **
tierDIAMOND -0.2099257 0.1221066 -1.719 0.085578 .
goldEarned:individualPositionBOTTOM 5.7346544 0.6640271 8.636 < 2e-16 ***
goldEarned:individualPositionMIDDLE 4.9490595 0.6498041 7.616 2.61e-14 ***
goldEarned:individualPositionJUNGLE 4.2850081 0.6474130 6.619 3.62e-11 ***
goldEarned:individualPositionTOP 4.0531294 0.6476428 6.258 3.89e-10 ***
goldEarned:tierBRONZE -0.0849957 0.7565685 -0.112 0.910551
goldEarned:tierSILVER -0.0440435 0.7426111 -0.059 0.952706
goldEarned:tierGOLD 0.3153522 0.7529545 0.419 0.675348
goldEarned:tierPLATINUM 1.7835490 0.7827785 2.278 0.022698 *
goldEarned:tierDIAMOND 0.8439319 0.7536048 1.120 0.262773
individualPositionBOTTOM:tierBRONZE 0.1114395 0.1799761 0.619 0.535791
individualPositionMIDDLE:tierBRONZE -0.0803993 0.1743837 -0.461 0.644764
individualPositionJUNGLE:tierBRONZE 0.2750908 0.1755888 1.567 0.117191
individualPositionTOP:tierBRONZE -0.3524101 0.1741484 -2.024 0.043009 *
individualPositionBOTTOM:tierSILVER -0.1903623 0.1751922 -1.087 0.277218
individualPositionMIDDLE:tierSILVER 0.1201389 0.1700873 0.706 0.479979
individualPositionJUNGLE:tierSILVER 0.1484385 0.1716677 0.865 0.387212
individualPositionTOP:tierSILVER -0.1245770 0.1693526 -0.736 0.461970
individualPositionBOTTOM:tierGOLD -0.1700483 0.1748046 -0.973 0.330657
individualPositionMIDDLE:tierGOLD 0.4676913 0.1704174 2.744 0.006062 **
individualPositionJUNGLE:tierGOLD 0.0560445 0.1712902 0.327 0.743524
individualPositionTOP:tierGOLD -0.0845517 0.1686760 -0.501 0.616183
individualPositionBOTTOM:tierPLATINUM 0.2230046 0.1782083 1.251 0.210799
individualPositionMIDDLE:tierPLATINUM 0.5272124 0.1748173 3.016 0.002563 **
individualPositionJUNGLE:tierPLATINUM 0.3151809 0.1752976 1.798 0.072181 .
individualPositionTOP:tierPLATINUM 0.3442697 0.1722330 1.999 0.045623 *
individualPositionBOTTOM:tierDIAMOND -0.0390518 0.1700383 -0.230 0.818352
individualPositionMIDDLE:tierDIAMOND 0.5486186 0.1666078 3.293 0.000992 ***
individualPositionJUNGLE:tierDIAMOND -0.0196129 0.1661978 -0.118 0.906060
individualPositionTOP:tierDIAMOND 0.2649390 0.1641395 1.614 0.106504
goldEarned:individualPositionBOTTOM:tierBRONZE -0.5410284 0.9565154 -0.566 0.571649
goldEarned:individualPositionMIDDLE:tierBRONZE 0.4059998 0.9374082 0.433 0.664936
goldEarned:individualPositionJUNGLE:tierBRONZE -1.1519592 0.9454214 -1.218 0.223049
goldEarned:individualPositionTOP:tierBRONZE 1.7324872 0.9367984 1.849 0.064404 .
goldEarned:individualPositionBOTTOM:tierSILVER 0.8976081 0.9371119 0.958 0.338141
goldEarned:individualPositionMIDDLE:tierSILVER -0.4794273 0.9214764 -0.520 0.602867
goldEarned:individualPositionJUNGLE:tierSILVER -0.4136301 0.9304532 -0.445 0.656647
goldEarned:individualPositionTOP:tierSILVER 0.7022446 0.9185403 0.765 0.444556
goldEarned:individualPositionBOTTOM:tierGOLD 0.7741899 0.9440787 0.820 0.412189
goldEarned:individualPositionMIDDLE:tierGOLD -2.1321757 0.9320332 -2.288 0.022157 *
goldEarned:individualPositionJUNGLE:tierGOLD 0.0625770 0.9376650 0.067 0.946791
goldEarned:individualPositionTOP:tierGOLD 0.5259145 0.9252041 0.568 0.569743
goldEarned:individualPositionBOTTOM:tierPLATINUM -1.4223405 0.9719356 -1.463 0.143355
goldEarned:individualPositionMIDDLE:tierPLATINUM -2.7415891 0.9644264 -2.843 0.004473 **
goldEarned:individualPositionJUNGLE:tierPLATINUM -1.4908005 0.9668010 -1.542 0.123075
goldEarned:individualPositionTOP:tierPLATINUM -1.8674175 0.9549370 -1.956 0.050519 .
goldEarned:individualPositionBOTTOM:tierDIAMOND 0.1081900 0.9315740 0.116 0.907544
goldEarned:individualPositionMIDDLE:tierDIAMOND -2.5436799 0.9238311 -2.753 0.005898 **
goldEarned:individualPositionJUNGLE:tierDIAMOND 0.3662858 0.9206385 0.398 0.690733
goldEarned:individualPositionTOP:tierDIAMOND -1.1915075 0.9152201 -1.302 0.192957
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 943982 on 680939 degrees of freedom
Residual deviance: 943423 on 680880 degrees of freedom
AIC: 943543
Number of Fisher Scoring iterations: 3
Results are unclear, for lower elo’s in general, gold percentage is less important on ADC but it’s not super clear based on the the variance in Silver and Platinum. Interestingly, jungle seems to be more of a carry role in higher elos. Might be because of the champion choice. This will be examined later.
summary(results$models$damageDoneChamp)
Call:
glm(formula = win ~ totalDamageDealtToChampions * individualPosition,
family = "binomial", data = gameInfo %>% filter(individualPosition !=
"Invalid"))
Deviance Residuals:
Min 1Q Median 3Q Max
-2.5621 -1.1437 0.6297 1.1823 1.4300
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.946e-01 9.132e-03 -21.31 <2e-16 ***
totalDamageDealtToChampions 1.711e-05 6.419e-07 26.66 <2e-16 ***
individualPositionBOTTOM -3.756e-01 1.428e-02 -26.30 <2e-16 ***
individualPositionMIDDLE -3.821e-01 1.459e-02 -26.18 <2e-16 ***
individualPositionJUNGLE -2.814e-01 1.389e-02 -20.26 <2e-16 ***
individualPositionTOP -3.024e-01 1.452e-02 -20.82 <2e-16 ***
totalDamageDealtToChampions:individualPositionBOTTOM 1.429e-05 8.256e-07 17.31 <2e-16 ***
totalDamageDealtToChampions:individualPositionMIDDLE 1.244e-05 8.207e-07 15.16 <2e-16 ***
totalDamageDealtToChampions:individualPositionJUNGLE 1.123e-05 8.450e-07 13.29 <2e-16 ***
totalDamageDealtToChampions:individualPositionTOP 1.019e-05 8.384e-07 12.15 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 943982 on 680939 degrees of freedom
Residual deviance: 930273 on 680930 degrees of freedom
AIC: 930293
Number of Fisher Scoring iterations: 4
results$plots$damageDoneChamp <- plot_model(damageDoneChamp.fit, type = "int")
Data were 'prettified'. Consider using `terms="totalDamageDealtToChampions [all]"` to get smooth plots.
results$plots$damageDoneChamp
Not much difference based on whoever does damage to champion aside from support. ## Average Total Damage and Damage to Champions based on Role
data.temp$damageDone <- gameInfo %>%
filter(individualPosition != "Invalid") %>%
select(individualPosition, totalDamageDealtToChampions, totalDamageDealt)
data.temp$damageDone %>%
ggplot(aes(x = individualPosition, y = totalDamageDealt)) +
geom_boxplot()
data.temp$damageDone %>%
ggplot(aes(x = individualPosition, y = totalDamageDealtToChampions)) +
geom_boxplot()
data.temp$damageDone %>%
filter(individualPosition != "Invalid") %>%
group_by(individualPosition) %>%
summarize(avg_damage_champ = mean(totalDamageDealtToChampions), avg_damage_total = mean(totalDamageDealt))
kruskal.test(totalDamageDealt~individualPosition, data = data.temp$damageDone)
Kruskal-Wallis rank sum test
data: totalDamageDealt by individualPosition
Kruskal-Wallis chi-squared = 245961, df = 4, p-value < 2.2e-16
pairwise.wilcox.test(data.temp$damageDone$totalDamageDealt, data.temp$damageDone$individualPosition, p.adjust.method = "fdr")
Pairwise comparisons using Wilcoxon rank sum test with continuity correction
data: data.temp$damageDone$totalDamageDealt and data.temp$damageDone$individualPosition
UTILITY BOTTOM MIDDLE JUNGLE
BOTTOM < 2e-16 - - -
MIDDLE < 2e-16 < 2e-16 - -
JUNGLE < 2e-16 < 2e-16 < 2e-16 -
TOP < 2e-16 4.3e-07 < 2e-16 < 2e-16
P value adjustment method: fdr
Not really useful, sample size is so large which makes any small difference significant. Visual analysis of boxplots probably more useful.
data.temp$championDifficulty <- gameInfo %>%
left_join(
champions.scraped %>%
select(name, difficulty),
by = c("championName" = "name")
) %>%
filter(!is.na(difficulty))
results$models$championDifficulty <- glm(win ~ difficulty*tier, data = data.temp$championDifficulty, family = "binomial")
summary(results$models$championDifficulty)
Call:
glm(formula = win ~ difficulty * tier, family = "binomial", data = data.temp$championDifficulty)
Deviance Residuals:
Min 1Q Median 3Q Max
-1.19278 -1.17777 0.00661 1.17705 1.20620
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 0.0268696 0.0102058 2.633 0.00847 **
difficultyAverage -0.0437489 0.0174334 -2.509 0.01209 *
difficultyHard -0.0290928 0.0211231 -1.377 0.16842
difficultySevere -0.0911225 0.0221172 -4.120 3.79e-05 ***
tierBRONZE 0.0092404 0.0142805 0.647 0.51759
tierSILVER 0.0016172 0.0137644 0.117 0.90647
tierGOLD -0.0044844 0.0137115 -0.327 0.74363
tierPLATINUM -0.0068397 0.0141503 -0.483 0.62884
tierDIAMOND -0.0053488 0.0135708 -0.394 0.69348
difficultyAverage:tierBRONZE 0.0024604 0.0242620 0.101 0.91923
difficultyHard:tierBRONZE -0.0443339 0.0291447 -1.521 0.12822
difficultySevere:tierBRONZE -0.0124684 0.0301496 -0.414 0.67920
difficultyAverage:tierSILVER 0.0161154 0.0230530 0.699 0.48452
difficultyHard:tierSILVER -0.0124918 0.0273823 -0.456 0.64825
difficultySevere:tierSILVER -0.0001723 0.0282654 -0.006 0.99514
difficultyAverage:tierGOLD 0.0219788 0.0226007 0.972 0.33081
difficultyHard:tierGOLD 0.0013287 0.0264725 0.050 0.95997
difficultySevere:tierGOLD 0.0240251 0.0275498 0.872 0.38318
difficultyAverage:tierPLATINUM 0.0294448 0.0229928 1.281 0.20033
difficultyHard:tierPLATINUM 0.0152147 0.0264962 0.574 0.56582
difficultySevere:tierPLATINUM 0.0211271 0.0275086 0.768 0.44248
difficultyAverage:tierDIAMOND 0.0181623 0.0219523 0.827 0.40804
difficultyHard:tierDIAMOND 0.0080260 0.0252925 0.317 0.75099
difficultySevere:tierDIAMOND 0.0392715 0.0264616 1.484 0.13778
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 945480 on 682019 degrees of freedom
Residual deviance: 945352 on 681996 degrees of freedom
AIC: 945400
Number of Fisher Scoring iterations: 3
results$plots$championDifficulty <- plot_model(results$models$championDifficulty, type = "int")
results$plots$championDifficulty
Hard to say - I might have expected that win rate of difficult champions would increase when we get to higher ranks. Difficulty however, does not take into account meta and other interactions. The model generated doesn’t have the greatest significance so interpretability is limited. It is striking however, the general trend of winrate decreasing with the increase of champion difficulty. Maybe if we interpret difficulty as an ordinal variable we might see a significant linear regression model.
A soft takeaway then is play easier champions…at least easier as defined by mobalytics.